package org.jeecg.modules.cascv.image.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;


public class ByteUtil {


    public static String getByteToString(byte[] bytes, int start, int len) {


        byte[] bytes_cut = new byte[len];

        System.arraycopy(bytes, start, bytes_cut, 0, len);

        StringBuffer result = new StringBuffer();
        for (int m = 0; m < bytes_cut.length; m++) {

            byte b = bytes_cut[m];

            int h = 0xf & (b >>> 4);
            int l = 0xf & b;

            String s = (Integer.toHexString(h) + Integer.toHexString(l)).toUpperCase();

            result.append(s);
        }

        return result.toString();

    }

    /**
     * @param bytes
     * @param start
     * @param len
     * @return
     */
    public static long getBytesToLong(byte[] bytes, int start, int len) {


        byte[] bytes_cut = new byte[len];

        if ((start + len) > bytes.length) {
            System.arraycopy(bytes, start, bytes_cut, 0, start + len - bytes.length);
        } else {
            System.arraycopy(bytes, start, bytes_cut, 0, len);
        }

        long value = 0;

        for (int i = 0; i < bytes_cut.length; i++) {
            value += (bytes_cut[i] & 0xff) << (8 * (bytes_cut.length - 1 - i));
        }

        return value;

    }


    public static int getByteToInt(byte byte1, byte byte2) {

        int h1 = 0xf & (byte1 >>> 4);
        int l1 = 0xf & byte1;

        int h2 = 0xf & (byte2 >>> 4);
        int l2 = 0xf & byte2;

        h1 = h1 << 12;
        l1 = l1 << 8;
        h2 = h2 << 4;

        int len_new = h1 + l1 + h2 + l2;

        return len_new;
    }


    public static String getByteToString_reverse(byte[] bytes, int start, int len, int reverse_step) {


        byte[] bytes_cut = new byte[len];

        System.arraycopy(bytes, start, bytes_cut, 0, len);

        bytes_cut = reverseByte(bytes_cut, reverse_step);

        StringBuffer result = new StringBuffer();
        for (int m = 0; m < bytes_cut.length; m++) {

            byte b = bytes_cut[m];

            int h = 0xf & (b >>> 4);
            int l = 0xf & b;

            String s = (Integer.toHexString(h) + Integer.toHexString(l)).toUpperCase();

            result.append(s);
        }

        return result.toString();

    }


    public static String getByteToString(List<Byte> bytes) {

        StringBuffer result = new StringBuffer();

        for (int m = 0; m < bytes.size(); m++) {

            byte b = bytes.get(m);

            int h = 0xf & (b >>> 4);
            int l = 0xf & b;

            String s = (Integer.toHexString(h) + Integer.toHexString(l)).toUpperCase();

            result.append(s);
        }

        return result.toString();

    }


    public static byte[] reverseByte(byte[] bytes, int step) {

        byte[] newbyte = new byte[bytes.length];

        for (int i = 0; i < bytes.length; i = i + step) {


            for (int j = 0; j < step; j++) {

                newbyte[i + j] = bytes[i + step - j - 1];

            }

            //System.out.println(getByteToString(newbyte, i, step));
        }

        return newbyte;
    }


    public static byte[] getBytes(String hexContent) {

        byte[] bytes = new byte[hexContent.length() / 2];
        for (int i = 0; i < hexContent.length(); i += 2) {
            //d1
            String substring = hexContent.substring(i, i + 2);

            int i1 = Integer.parseInt(substring, 16);

            bytes[i / 2] = (byte) i1;
        }
        return bytes;
    }

    public static byte[] getBytes(int hexInt, int byteNum) {
        String s = Integer.toHexString(hexInt);
        String stringByByteCount = getStringByByteCount(s, byteNum);
        byte[] bytes = getBytes(stringByByteCount);
        return bytes;
    }

    public static byte[] getBytes(float f, int byteNum) {
        int floatToIntBits = Float.floatToIntBits(f);
        String s = Integer.toHexString(floatToIntBits);
        String stringByByteCount = getStringByByteCount(s, byteNum);
        byte[] bytes = getBytes(stringByByteCount);
        return bytes;
    }


    public static byte[] getBytes_Long(long hexInt, int byteNum) {
        String s = Long.toHexString(hexInt);
        String stringByByteCount = getStringByByteCount(s, byteNum);
        byte[] bytes = getBytes(stringByByteCount);
        return bytes;
    }


    public static String getBytes_STR(int hexInt, int byteNum) {
        String s = Integer.toHexString(hexInt);
        String stringByByteCount = getStringByByteCount(s, byteNum);
        return stringByByteCount.toUpperCase();
    }

    public static String getBytes_STR(long hexInt, int byteNum) {
        String s = Long.toHexString(hexInt);
        String stringByByteCount = getStringByByteCount(s, byteNum);
        return stringByByteCount.toUpperCase();
    }

    public static String getStringByByteCount(String hexString, int bytesCount) {
        StringBuilder builder = new StringBuilder();
        int zeroAddCount = bytesCount * 2 - hexString.length();
        if (zeroAddCount < 0) {
            return hexString.substring(0, bytesCount * 2);
        }
        for (int i = 0; i < zeroAddCount; i++) {
            builder.append("0");
        }
        return builder.append(hexString).toString();
    }

    public static int getByteIndex(byte[] src, byte[] mBaseData) {

        int i = 0;

        while (i < mBaseData.length) {

            if (mBaseData[i] == src[0] && mBaseData[i + 1] == src[i]) {
                return i;
            } else {
                i++;
            }

        }

        return -1;

    }

    /**
     * 4bytes 秒
     *
     * @param currentTimeMillis
     * @return
     */
    public static byte[] get4BytesSecond(long currentTimeMillis, long shipTime) {

        //long shipTime = BaseTimeUtil.computeShipTimeByBJTime(currentTimeMillis);
        long diffSecond = shipTime / 1000;
        String secondHexString = getStringByByteCount(Long.toHexString(diffSecond), 4);
        byte[] second = getBytes(secondHexString);
        return second;
    }

    public static byte[] get2BytesMilliSecond(long currentTimeMillis) {
        long milliSecond = currentTimeMillis % 1000;
        String milliHexString = getStringByByteCount(Long.toHexString(milliSecond), 2);
        byte[] sub = getBytes(milliHexString);
        return sub;
    }

    public static byte[] get2BytesMilliSecond_ym(long currentTimeMillis) {
        long milliSecond = currentTimeMillis % 1000;
        milliSecond = milliSecond / 25;
        String milliHexString = getStringByByteCount(Long.toHexString(milliSecond), 2);
        byte[] sub = getBytes(milliHexString);
        return sub;
    }

    public static byte[] getBytes_LH(int hexInt, int byteNum) {

        String s = Integer.toHexString(hexInt);
        String stringByByteCount = getStringByByteCount(s, byteNum);
        byte[] bytes = getBytes_LH(stringByByteCount);
        return bytes;
    }

    public static byte[] getBytes_LH(String hexContent) {

        byte[] bytes = new byte[hexContent.length() / 2];

        int n = 0;
        for (int i = hexContent.length(); i > 0; i -= 2) {
            //d1
            String substring = hexContent.substring(i - 2, i);

            int i1 = Integer.parseInt(substring, 16);

            bytes[n] = (byte) i1;

            n++;
        }
        return bytes;
    }

    //补位字节
    public static byte[] getFilledBytes(int fillByteCount, String fillContent) {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < fillByteCount; i++) {
            builder.append(fillContent);
        }
        return ByteUtil.getBytes(builder.toString());
    }


    /**
     * @param hexContent "D1D1"
     * @return
     */
    public static int[] getBytes_Integer(String hexContent) {

        int[] bytes = new int[hexContent.length() / 2];
        for (int i = 0; i < hexContent.length(); i += 2) {
            //d1
            String substring = hexContent.substring(i, i + 2);

            int i1 = Integer.parseInt(substring, 16);

            bytes[i / 2] = i1;
        }
        return bytes;
    }

    public static int[] getBytes_Integer(String hexContent,int step) {

        int[] bytes = new int[hexContent.length() / step];

        for (int i = 0; i < hexContent.length(); i += step) {
            //d1
            String substring = hexContent.substring(i, i + step);

            int i1 = Integer.parseInt(substring, 16);

            bytes[i / step] = i1;
        }
        return bytes;
    }


    public static String getFileByte_Pix(File file, int len) {

        String pix = "";

        FileInputStream fis = null;
        try {

            fis = new FileInputStream(file);
            byte[] readbytes = new byte[len];

            while (fis.read(readbytes) != -1) {

                pix = ByteUtil.getByteToString(readbytes, 0, readbytes.length);

                break;

            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        return pix;

    }

    /**
     * 从指定数组查找另一数组，返回起始位置集合
     *
     * @param bytes
     * @param findbytes
     * @return
     */
    public static List<Integer> getIndex(byte[] bytes, byte[] findbytes) {

        List<Integer> indexlist = new ArrayList();
        if (bytes.length >= findbytes.length) {

            for (int i = 0; i < bytes.length; i++) {

                if (bytes[i] == findbytes[0]) {
                    if (bytes.length - i >= findbytes.length) {
                        boolean isfind = true;
                        for (int j = 0; j < findbytes.length; j++) {
                            if (findbytes[j] != bytes[i + j]) {
                                isfind = false;
                            }
                        }
                        if (isfind) {
                            indexlist.add(i);
                            i = i + findbytes.length;
                        }
                    }
                }
            }
        }
        return indexlist;

    }

    public static float[] getBytes_Float(String hexContent, int step) {

        float[] bytes = new float[hexContent.length() / step];

        for (int i = 0; i < hexContent.length() ; i += step) {
            //d1
            String substring = hexContent.substring(i, i + step);

            byte[] bytes1 = ByteUtil.getBytes(substring);

            bytes1 = ByteUtil.reverseByte(bytes1,bytes1.length);

            String newstr = ByteUtil.getByteToString(bytes1,0,bytes1.length);

            BigInteger valueint = BigInteger.valueOf(Long.parseUnsignedLong(newstr, 16));

            float f = Float.intBitsToFloat(valueint.intValue());
            //System.out.println(newstr+","+f);

            bytes[i / step] = f;

        }
        return bytes;
    }

    public static float[] getMinMax_Float(float[] imgbyte_float, int tvalue, int tnum) {

        float[] result = new float[2];

        TreeSet<Float> treeSet = new TreeSet<>();
        float max = 0;
        for (Float i : imgbyte_float) {
            if (i > max) {
                max = i;
            }
            treeSet.add(i);
        }
        float old = 0f;
        float count = 0f;
        System.out.println(treeSet);

        float setmin = treeSet.first();
        float setmax = treeSet.last();

        System.out.println("setmin_float_old=" + setmin);
        System.out.println("setmax_float_old=" + setmax);

        for (Float i : treeSet) {

            if (count == 0) {
                old = i;
                setmin = i;
            }

            if (count > 0) {
                float dec = i - old;
                if (count < tnum) {
                    if (dec > tvalue && old == setmin) {
                        setmin = i;
                    }
                }
                if (count > treeSet.size() - tnum) {
                    if (dec < tvalue && old != setmin) {
                        setmax = i;
                    }
                    if (dec > tvalue && old != setmin) {
                        break;
                    }
                }
                old = i;
            }
            count++;
        }
        System.out.println("setmin_float=" + setmin);
        System.out.println("setmax_float=" + setmax);

        result[0] = setmin;
        result[1] = setmax;

        return result;
    }

}
